package transfers

import (
	"lifi"
	"log"
	"plugin"
)

type Creator func() lifi.Transfer

var Transfers = map[string]Creator{}

type ProxyTransfer struct {
	p       *plugin.Plugin
	start   func(collector lifi.Collector) error
	stop    func()
	process func(lifi.Data, lifi.Collector) error
	init    func() error
}

func (p ProxyTransfer) Start(collector lifi.Collector) error {
	return p.start(collector)
}

func (p ProxyTransfer) Stop() {
	p.stop()
}

func (p ProxyTransfer) Process(d lifi.Data, acc lifi.Collector) error {
	return p.process(d, acc)
}

func (p *ProxyTransfer) Init() error {
	return p.init()
}

func NewProxyTransfer(p *plugin.Plugin) lifi.Transfer {
	pt := &ProxyTransfer{p: p}
	// start 方法
	StartSym, err := p.Lookup("Start") // 查找插件中的符号
	if err != nil {
		log.Fatal(err)
	}

	Start, ok := StartSym.(func(collector lifi.Collector) error)
	if !ok {
		log.Fatalf("unexpected type for Start: %T", StartSym)
	}
	pt.start = Start

	// stop 方法
	StopSym, err := p.Lookup("Stop") // 查找插件中的符号
	if err != nil {
		log.Fatal(err)
	}

	Stop, ok := StopSym.(func())
	if !ok {
		log.Fatalf("unexpected type for Start: %T", StartSym)
	}
	pt.stop = Stop

	// process 方法
	ProcessSym, err := p.Lookup("Process") // 查找插件中的符号
	if err != nil {
		log.Fatal(err)
	}

	Process, ok := ProcessSym.(func(lifi.Data, lifi.Collector) error)
	if !ok {
		log.Fatalf("unexpected type for Process: %T", ProcessSym)
	}
	pt.process = Process

	// init 方法
	InitSym, err := p.Lookup("Init") // 查找插件中的符号
	if err != nil {
		log.Fatal(err)
	}

	Init, ok := InitSym.(func() error)
	if !ok {
		log.Fatalf("unexpected type for Init: %T", InitSym)
	}
	pt.init = Init

	return pt
}
func Add(name string, creator Creator) {
	Transfers[name] = creator
}

func AddPlugin(name string, pluginPath string) {
	p, err := plugin.Open(pluginPath) // 加载插件
	if err != nil {
		log.Fatal(err)
	}
	creator := func() lifi.Transfer {

		return NewProxyTransfer(p)
	}
	Transfers[name] = creator

}
